home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / sdk / vfw11.win / vfwdk / dib.c_ / dib.bin
Encoding:
Text File  |  1993-11-19  |  16.2 KB  |  672 lines

  1. /*----------------------------------------------------------------------------*\
  2. |   Routines for dealing with Device independent bitmaps                       |
  3. \*----------------------------------------------------------------------------*/
  4. /**************************************************************************
  5.  *
  6.  *  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  7.  *  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  8.  *  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  9.  *  PURPOSE.
  10.  *
  11.  *  Copyright (c) 1992, 1993  Microsoft Corporation.  All Rights Reserved.
  12.  * 
  13.  **************************************************************************/
  14.  
  15. #include <windows.h>
  16. #include "dib.h"
  17.  
  18. /* flags for _lseek */
  19. #define  SEEK_CUR 1
  20. #define  SEEK_END 2
  21. #define  SEEK_SET 0
  22.  
  23. #define BFT_ICON   0x4349   /* 'IC' */
  24. #define BFT_BITMAP 0x4d42   /* 'BM' */
  25. #define BFT_CURSOR 0x5450   /* 'PT' */
  26.  
  27. #define ISDIB(bft) ((bft) == BFT_BITMAP)
  28.  
  29. #define PALVERSION      0x300
  30. #define MAXPALETTE      256
  31.  
  32. /*
  33.  *   Open a DIB file and return a MEMORY DIB, a memory handle containing..
  34.  *
  35.  *   BITMAP INFO    bi
  36.  *   palette data
  37.  *   bits....
  38.  *
  39.  */
  40. HDIB OpenDIB(LPSTR szFile)
  41. {
  42.     int            fh;
  43.     LPBITMAPINFOHEADER  lpbi;
  44.     DWORD        dwLen;
  45.     HDIB                hdib;
  46.     HANDLE              h;
  47.     OFSTRUCT            of;
  48.  
  49.     if (HIWORD((DWORD)szFile) == 0)
  50.     {
  51.         fh = LOWORD((DWORD)szFile);
  52.     }
  53.     else
  54.     {
  55.         fh = OpenFile(szFile, &of, OF_READ);
  56.     }
  57.  
  58.     if (fh == -1)
  59.     return NULL;
  60.  
  61.     hdib = ReadDibBitmapInfo(fh);
  62.  
  63.     if (!hdib) 
  64.     goto error;
  65.  
  66.     lpbi = (LPVOID)GlobalLock(hdib);
  67.  
  68.     /* How much memory do we need to hold the DIB */
  69.  
  70.     dwLen  = DibSize(lpbi);
  71.  
  72.     /* Can we get more memory? */
  73.  
  74.     h = GlobalReAlloc(hdib,dwLen,0);
  75.  
  76.     if (!h)
  77.     {
  78.     GlobalFree(hdib);
  79.     hdib = NULL;
  80.     }
  81.     else
  82.     {
  83.     hdib = h;
  84.     }
  85.  
  86.     if (hdib)
  87.     {
  88.         lpbi = (LPVOID)GlobalLock(hdib);
  89.  
  90.     /* read in the bits */
  91.         _hread(fh, DibPtr(lpbi), lpbi->biSizeImage);
  92.     }
  93.  
  94. error:
  95.     if (HIWORD((DWORD)szFile) != 0)
  96.         _lclose(fh);
  97.  
  98.     return hdib;
  99. }
  100.  
  101. /*
  102.  *   Write a global handle in CF_DIB format to a file.
  103.  *
  104.  */
  105. BOOL WriteDIB(LPSTR szFile,HDIB hdib)
  106. {
  107.     BITMAPFILEHEADER    hdr;
  108.     LPBITMAPINFOHEADER  lpbi;
  109.     int                 fh;
  110.     OFSTRUCT            of;
  111.  
  112.     if (!hdib)
  113.     return FALSE;
  114.  
  115.     if (HIWORD((DWORD)szFile) == 0)
  116.     {
  117.         fh = LOWORD((DWORD)szFile);
  118.     }
  119.     else
  120.     {
  121.         fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
  122.     }
  123.  
  124.     if (fh == -1)
  125.         return FALSE;
  126.  
  127.     lpbi = (LPVOID)GlobalLock(hdib);
  128.  
  129.     hdr.bfType        = BFT_BITMAP;
  130.     hdr.bfSize          = DibSize(lpbi) + sizeof(BITMAPFILEHEADER);
  131.     hdr.bfReserved1     = 0;
  132.     hdr.bfReserved2     = 0;
  133.     hdr.bfOffBits       = (DWORD)sizeof(BITMAPFILEHEADER) +
  134.                           lpbi->biSize + lpbi->biClrUsed * sizeof(RGBQUAD);
  135.  
  136.     _lwrite(fh,(LPVOID)&hdr,sizeof(BITMAPFILEHEADER));
  137.     _hwrite(fh,(LPVOID)lpbi,DibSize(lpbi));
  138.  
  139.     GlobalUnlock(hdib);
  140.  
  141.     if (HIWORD((DWORD)szFile) != 0)
  142.         _lclose(fh);
  143.  
  144.     return TRUE;
  145. }
  146.  
  147. /*
  148.  *  CreateBIPalette()
  149.  *
  150.  *  Given a Pointer to a BITMAPINFO struct will create a
  151.  *  a GDI palette object from the color table.
  152.  *
  153.  */
  154. HPALETTE CreateBIPalette(LPBITMAPINFOHEADER lpbi)
  155. {
  156.     LOGPALETTE          *pPal;
  157.     HPALETTE            hpal = NULL;
  158.     WORD                nNumColors;
  159.     int                 i;
  160.     RGBQUAD        FAR *pRgb;
  161.  
  162.     if (!lpbi)
  163.     return NULL;
  164.  
  165.     nNumColors = DibNumColors(lpbi);
  166.  
  167.     if (nNumColors)
  168.     {
  169.         pRgb = DibColors(lpbi);
  170.     pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
  171.  
  172.         if (!pPal)
  173.             goto exit;
  174.  
  175.         pPal->palNumEntries = nNumColors;
  176.     pPal->palVersion    = PALVERSION;
  177.  
  178.         for (i = 0; i < (int)nNumColors; i++)
  179.     {
  180.         pPal->palPalEntry[i].peRed     = pRgb->rgbRed;
  181.         pPal->palPalEntry[i].peGreen = pRgb->rgbGreen;
  182.         pPal->palPalEntry[i].peBlue  = pRgb->rgbBlue;
  183.         pPal->palPalEntry[i].peFlags = (BYTE)0;
  184.             pRgb++;
  185.         }
  186.  
  187.         hpal = CreatePalette(pPal);
  188.         LocalFree((HANDLE)pPal);
  189.     }
  190.  
  191. exit:
  192.     return hpal;
  193. }
  194.  
  195. /*
  196.  *  ReadDibBitmapInfo()
  197.  *
  198.  *  Will read a file in DIB format and return a global HANDLE to it's
  199.  *  BITMAPINFO.  This function will work with both "old" and "new"
  200.  *  bitmap formats, but will allways return a "new" BITMAPINFO
  201.  *
  202.  */
  203. HDIB ReadDibBitmapInfo(int fh)
  204. {
  205.     DWORD     off;
  206.     HDIB    hbi = NULL;
  207.     int       size;
  208.     int       i;
  209.     WORD      nNumColors;
  210.  
  211.     RGBQUAD FAR       *pRgb;
  212.     BITMAPINFOHEADER   bi;
  213.     BITMAPCOREHEADER   bc;
  214.     LPBITMAPINFOHEADER lpbi;
  215.     BITMAPFILEHEADER   bf;
  216.  
  217.     if (fh == -1)
  218.         return NULL;
  219.  
  220.     off = _llseek(fh,0L,SEEK_CUR);
  221.  
  222.     if (sizeof(bf) != _lread(fh,(LPVOID)&bf,sizeof(bf)))
  223.         return NULL;
  224.  
  225.     /*
  226.      *  do we have a RC HEADER?
  227.      */
  228.     if (!ISDIB(bf.bfType))
  229.     {
  230.         bf.bfOffBits = 0L;
  231.         _llseek(fh,off,SEEK_SET);
  232.     }
  233.  
  234.     if (sizeof(bi) != _lread(fh,(LPVOID)&bi,sizeof(bi)))
  235.         return NULL;
  236.  
  237.     nNumColors = DibNumColors(&bi);
  238.  
  239.     /*
  240.      *  what type of bitmap info is this?
  241.      */
  242.     switch (size = (int)bi.biSize)
  243.     {
  244.         default:
  245.         case sizeof(BITMAPINFOHEADER):
  246.             break;
  247.  
  248.         case sizeof(BITMAPCOREHEADER):
  249.             bc = *(BITMAPCOREHEADER*)&bi;
  250.             bi.biSize               = sizeof(BITMAPINFOHEADER);
  251.             bi.biWidth              = (DWORD)bc.bcWidth;
  252.             bi.biHeight             = (DWORD)bc.bcHeight;
  253.             bi.biPlanes             =  (WORD)bc.bcPlanes;
  254.             bi.biBitCount           =  (WORD)bc.bcBitCount;
  255.             bi.biCompression        = BI_RGB;
  256.             bi.biSizeImage          = 0;
  257.             bi.biXPelsPerMeter      = 0;
  258.             bi.biYPelsPerMeter      = 0;
  259.             bi.biClrUsed            = nNumColors;
  260.             bi.biClrImportant       = nNumColors;
  261.  
  262.             _llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
  263.  
  264.             break;
  265.     }
  266.  
  267.     /*
  268.      *    fill in some default values!
  269.      */
  270.     if (bi.biSizeImage == 0)
  271.         bi.biSizeImage = DibSizeImage(&bi);
  272.  
  273.     if (bi.biClrUsed == 0)
  274.     bi.biClrUsed = DibNumColors(&bi);
  275.  
  276.     hbi = GlobalAlloc(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
  277.  
  278.     if (!hbi)
  279.         return NULL;
  280.  
  281.     lpbi = (VOID FAR *)GlobalLock(hbi);
  282.     *lpbi = bi;
  283.  
  284.     if (lpbi->biSize > sizeof(bi)) {
  285.     if (_lread(fh,
  286.            (LPBYTE) lpbi + sizeof(bi),
  287.            (UINT)lpbi->biSize - sizeof(bi))
  288.              != (lpbi->biSize - sizeof(bi))) {
  289.         GlobalFree(hbi);
  290.         return NULL;
  291.     }
  292.     }
  293.     
  294.     pRgb = DibColors(lpbi);
  295.  
  296.     if (nNumColors)
  297.     {
  298.         if (size == sizeof(BITMAPCOREHEADER))
  299.         {
  300.             /*
  301.              * convert a old color table (3 byte entries) to a new
  302.              * color table (4 byte entries)
  303.              */
  304.             _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBTRIPLE));
  305.  
  306.             for (i=nNumColors-1; i>=0; i--)
  307.             {
  308.                 RGBQUAD rgb;
  309.  
  310.                 rgb.rgbRed      = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
  311.                 rgb.rgbBlue     = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
  312.                 rgb.rgbGreen    = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
  313.                 rgb.rgbReserved = (BYTE)0;
  314.  
  315.                 pRgb[i] = rgb;
  316.             }
  317.         }
  318.         else
  319.         {
  320.             _lread(fh,(LPSTR)pRgb,nNumColors * sizeof(RGBQUAD));
  321.         }
  322.     }
  323.  
  324.     if (bf.bfOffBits != 0L)
  325.         _llseek(fh,off + bf.bfOffBits,SEEK_SET);
  326.  
  327.     return hbi;
  328. }
  329.  
  330. /*
  331.  *  DibFromBitmap()
  332.  *
  333.  *  Will create a global memory block in DIB format that represents the DDB
  334.  *  passed in
  335.  *
  336.  */
  337. HDIB DibFromBitmap(HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal, WORD wUsage)
  338. {
  339.     BITMAP               bm;
  340.     BITMAPINFOHEADER     bi;
  341.     BITMAPINFOHEADER FAR *lpbi;
  342.     DWORD                dwLen;
  343.     int                  nColors;
  344.     HDIB                 hdib;
  345.     HANDLE               h;
  346.     HDC                  hdc;
  347.  
  348.     if (!hbm)
  349.         return NULL;
  350.  
  351.     if (hpal == NULL)
  352.         hpal = GetStockObject(DEFAULT_PALETTE);
  353.  
  354.     GetObject(hbm,sizeof(bm),(LPSTR)&bm);
  355.     GetObject(hpal,sizeof(nColors),(LPSTR)&nColors);
  356.  
  357.     if (biBits == 0)
  358.         biBits = bm.bmPlanes * bm.bmBitsPixel;
  359.  
  360.     bi.biSize               = sizeof(BITMAPINFOHEADER);
  361.     bi.biWidth              = bm.bmWidth;
  362.     bi.biHeight             = bm.bmHeight;
  363.     bi.biPlanes             = 1;
  364.     bi.biBitCount           = biBits;
  365.     bi.biCompression        = biStyle;
  366.     bi.biSizeImage          = 0;
  367.     bi.biXPelsPerMeter      = 0;
  368.     bi.biYPelsPerMeter      = 0;
  369.     bi.biClrUsed            = 0;
  370.     bi.biClrImportant       = 0;
  371.  
  372.     dwLen  = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD);
  373.  
  374.     hdc = CreateCompatibleDC(NULL);
  375.     hpal = SelectPalette(hdc,hpal,FALSE);
  376.     RealizePalette(hdc);  // why is this needed on a MEMORY DC? GDI bug??
  377.  
  378.     hdib = GlobalAlloc(GMEM_MOVEABLE,dwLen);
  379.  
  380.     if (!hdib)
  381.         goto exit;
  382.  
  383.     lpbi = (VOID FAR *)GlobalLock(hdib);
  384.  
  385.     *lpbi = bi;
  386.  
  387.     /*
  388.      *  call GetDIBits with a NULL lpBits param, so it will calculate the
  389.      *  biSizeImage field for us
  390.      */
  391.     GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
  392.         NULL, (LPBITMAPINFO)lpbi, wUsage);
  393.  
  394.     bi = *lpbi;
  395.  
  396.     /*
  397.      * If the driver did not fill in the biSizeImage field, fill it in
  398.      * based on the width, height and bit depth.
  399.      */
  400.     if (bi.biSizeImage == 0)
  401.     {
  402.         bi.biSizeImage = (DWORD)WIDTHBYTES(bm.bmWidth * biBits) * bm.bmHeight;
  403.  
  404.         if (biStyle != BI_RGB)
  405.             bi.biSizeImage = (bi.biSizeImage * 3) / 2;
  406.     }
  407.  
  408.     /*
  409.      *  realloc the buffer big enough to hold all the bits
  410.      */
  411.     dwLen = bi.biSize + DibNumColors(&bi) * sizeof(RGBQUAD) + bi.biSizeImage;
  412.  
  413.     if (h = GlobalReAlloc(hdib,dwLen,0))
  414.     {
  415.         hdib = h;
  416.     }
  417.     else
  418.     {
  419.         GlobalFree(hdib);
  420.         hdib = NULL;
  421.         goto exit;
  422.     }
  423.  
  424.     /*
  425.      *  call GetDIBits with a NON-NULL lpBits param, and actualy get the
  426.      *  bits this time
  427.      */
  428.     lpbi = (VOID FAR *)GlobalLock(hdib);
  429.  
  430.     GetDIBits(hdc, hbm, 0, (WORD)bi.biHeight,
  431.         DibPtr(lpbi),(LPBITMAPINFO)lpbi, wUsage);
  432.  
  433.     bi = *lpbi;
  434.     lpbi->biClrUsed = DibNumColors(lpbi);
  435.  
  436. exit:
  437.     SelectPalette(hdc,hpal,FALSE);
  438.     DeleteDC(hdc);
  439.     return hdib;
  440. }
  441.  
  442. /*
  443.  *  BitmapFromDib()
  444.  *
  445.  *  Will create a DDB (Device Dependent Bitmap) given a global handle to
  446.  *  a memory block in CF_DIB format
  447.  *
  448.  */
  449. HBITMAP BitmapFromDib(HDIB hdib, HPALETTE hpal, WORD wUsage)
  450. {
  451.     LPBITMAPINFOHEADER lpbi;
  452.     HPALETTE    hpalT;
  453.     HDC         hdc;
  454.     HBITMAP     hbm;
  455.  
  456.     if (!hdib)
  457.         return NULL;
  458.  
  459.     lpbi = (LPVOID)GlobalLock(hdib);
  460.  
  461.     if (!lpbi)
  462.     return NULL;
  463.  
  464.     hdc = GetDC(NULL);
  465.  
  466.     if (hpal)
  467.     {
  468.         hpalT = SelectPalette(hdc,hpal,FALSE);
  469.         RealizePalette(hdc);
  470.     }
  471.  
  472.     hbm = CreateDIBitmap(hdc,(LPBITMAPINFOHEADER)lpbi,(LONG)CBM_INIT,
  473.                 DibPtr(lpbi),(LPBITMAPINFO)lpbi,wUsage);
  474.  
  475.     if (hpal && hpalT)
  476.         SelectPalette(hdc,hpalT,FALSE);
  477.  
  478.     ReleaseDC(NULL,hdc);
  479.  
  480.     return hbm;
  481. }
  482.  
  483. /*
  484.  *  SetDibUsage(hdib,hpal,wUsage)
  485.  *
  486.  *  Modifies the color table of the passed DIB for use with the wUsage
  487.  *  parameter specifed.
  488.  *
  489.  *  if wUsage is DIB_PAL_COLORS the DIB color table is set to 0-256
  490.  *  if wUsage is DIB_RGB_COLORS the DIB color table is set to the RGB values
  491.  *      in the passed palette
  492.  *
  493.  */
  494. BOOL SetDibUsage(HDIB hdib, HPALETTE hpal,WORD wUsage)
  495. {
  496.     LPBITMAPINFOHEADER lpbi;
  497.     PALETTEENTRY       ape[MAXPALETTE];
  498.     RGBQUAD FAR *      pRgb;
  499.     WORD FAR *         pw;
  500.     int                nColors;
  501.     int                n;
  502.  
  503.     if (hpal == NULL)
  504.         hpal = GetStockObject(DEFAULT_PALETTE);
  505.  
  506.     if (!hdib)
  507.         return FALSE;
  508.  
  509.     lpbi = (VOID FAR *)GlobalLock(hdib);
  510.  
  511.     if (!lpbi)
  512.     return FALSE;
  513.  
  514.     nColors = DibNumColors(lpbi);
  515.  
  516.     if (nColors > 0)
  517.     {
  518.         pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
  519.  
  520.         switch (wUsage)
  521.         {
  522.             //
  523.             // Set the DIB color table to palette indexes
  524.             //
  525.             case DIB_PAL_COLORS:
  526.                 for (pw = (WORD FAR*)pRgb,n=0; n<nColors; n++,pw++)
  527.                     *pw = n;
  528.                 break;
  529.  
  530.             //
  531.             // Set the DIB color table to RGBQUADS
  532.             //
  533.             default:
  534.             case DIB_RGB_COLORS:
  535.                 nColors = min(nColors,MAXPALETTE);
  536.  
  537.                 GetPaletteEntries(hpal,0,nColors,ape);
  538.  
  539.                 for (n=0; n<nColors; n++)
  540.                 {
  541.                     pRgb[n].rgbRed      = ape[n].peRed;
  542.                     pRgb[n].rgbGreen    = ape[n].peGreen;
  543.                     pRgb[n].rgbBlue     = ape[n].peBlue;
  544.                     pRgb[n].rgbReserved = 0;
  545.                 }
  546.                 break;
  547.         }
  548.     }
  549.     return TRUE;
  550. }
  551.  
  552. HDIB CreateDib(int bits, int dx, int dy)
  553. {
  554.     HDIB                hdib;
  555.     BITMAPINFOHEADER    bi;
  556.     LPBITMAPINFOHEADER  lpbi;
  557.     DWORD FAR *         pRgb;
  558.     int                 i;
  559.  
  560.     //
  561.     // These are the standard VGA colors, we will be stuck with until the
  562.     // end of time!
  563.     //
  564.     static DWORD CosmicColors[16] = {
  565.          0x00000000        // 0000  black
  566.         ,0x00800000        // 0001  dark red
  567.         ,0x00008000        // 0010  dark green
  568.         ,0x00808000        // 0011  mustard
  569.         ,0x00000080        // 0100  dark blue
  570.         ,0x00800080        // 0101  purple
  571.         ,0x00008080        // 0110  dark turquoise
  572.         ,0x00C0C0C0        // 1000  gray
  573.         ,0x00808080        // 0111  dark gray
  574.         ,0x00FF0000        // 1001  red
  575.         ,0x0000FF00        // 1010  green
  576.         ,0x00FFFF00        // 1011  yellow
  577.         ,0x000000FF        // 1100  blue
  578.         ,0x00FF00FF        // 1101  pink (magenta)
  579.         ,0x0000FFFF        // 1110  cyan
  580.         ,0x00FFFFFF        // 1111  white
  581.         };
  582.  
  583.     bi.biSize           = sizeof(BITMAPINFOHEADER);
  584.     bi.biPlanes         = 1;
  585.     bi.biBitCount       = bits;
  586.     bi.biWidth          = dx;
  587.     bi.biHeight         = dy;
  588.     bi.biCompression    = BI_RGB;
  589.     bi.biSizeImage      = 0;
  590.     bi.biXPelsPerMeter  = 0;
  591.     bi.biYPelsPerMeter  = 0;
  592.     bi.biClrUsed    = 0;
  593.     bi.biClrImportant   = 0;
  594.     bi.biClrUsed    = DibNumColors(&bi);
  595.  
  596.     hdib = GlobalAlloc(GMEM_MOVEABLE,sizeof(BITMAPINFOHEADER) +
  597.                 + (long)bi.biClrUsed * sizeof(RGBQUAD)
  598.                 + (long)DIBWIDTHBYTES(bi) * (long)dy);
  599.  
  600.     if (hdib)
  601.     {
  602.         lpbi  = (LPVOID)GlobalLock(hdib);
  603.         *lpbi = bi;
  604.  
  605.         pRgb  = (LPVOID)DibColors(lpbi);
  606.  
  607.         //
  608.         //  setup the color table
  609.         //
  610.         if (bits == 1)
  611.         {
  612.             pRgb[0] = CosmicColors[0];
  613.             pRgb[1] = CosmicColors[15];
  614.         }
  615.         else
  616.         {
  617.             for (i=0; i<16; i++)
  618.                 pRgb[i] = CosmicColors[i%16];
  619.         }
  620.     }
  621.  
  622.     return hdib;
  623. }
  624.  
  625. /*
  626.  *  StretchDib()
  627.  *
  628.  *  draws a bitmap in CF_DIB format, using StretchDIBits()
  629.  *
  630.  *  takes the same parameters as StretchBlt()
  631.  */
  632. BOOL StretchDib(HDC hdc, int x, int y, int dx, int dy, HDIB hdib, HPALETTE hpal, int x0, int y0, int dx0, int dy0, LONG rop, WORD wUsage)
  633. {
  634.     LPBITMAPINFOHEADER  lpbi;
  635.     HPALETTE            hpalT;
  636.     BOOL                f;
  637.  
  638.     if (!hdib)
  639.         return PatBlt(hdc,x,y,dx,dy,rop);
  640.  
  641.     if (hpal)
  642.     {
  643.         hpalT = SelectPalette(hdc, hpal, FALSE);
  644.         RealizePalette(hdc);
  645.     }
  646.  
  647.     lpbi = (LPVOID)GlobalLock(hdib);
  648.  
  649.     if (!lpbi)
  650.         return FALSE;
  651.  
  652.     if (dx0 == -1 && dy0 == -1)
  653.     {
  654.         dx0 = (int)lpbi->biWidth;
  655.         dy0 = (int)lpbi->biHeight;
  656.     }
  657.  
  658.     if (dx < 0 && dy < 0)
  659.     {
  660.         dx = dx0 * (-dx);
  661.         dy = dy0 * (-dy);
  662.     }
  663.  
  664.     f = StretchDIBits(hdc,x,y,dx,dy,x0,y0,dx0,dy0,
  665.         DibPtr(lpbi), (LPBITMAPINFO)lpbi,wUsage,rop) > 0;
  666.  
  667.     if (hpal && hpalT)
  668.         SelectObject(hdc, hpalT);
  669.  
  670.     return f;
  671. }
  672.